import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.border.Border;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.FileInputStream;

public class GamePanel extends JPanel {
    public static GamePanel Instance = new GamePanel();
    boolean isEmpty = true;
    int head = -1;
    int tail = -2;
    int PreHeadX = 75;/*起始坐标*/
    int PreHeadY = 75;/*起始坐标*/
    int PreTailX = 75;/*队尾坐标*/
    int PreTailY = 75;/*队尾坐标*/
    boolean preDomiIsDouble = false;/*前一张牌是横排中竖着摆的双牌*/
    boolean needVFlip = false;//需要竖直翻转
    boolean needHFlip = false;//需要水平翻转
    boolean isFollowHead = false;//接队头
    boolean isFollowTail = false;//接队尾
    //队头变向
    boolean isRtoD;
    boolean isDtoL;
    boolean isLtoU;
    //队尾变向
    boolean isDtoR;
    boolean isRtoU;
    boolean isUtoL;
    int preType  = -1;/*双牌判断坐标用0 - 横 */
    String HeadDirection = "right";
    String TailDirection = "down";
    public void Init(){
        Border ColorfulLine = BorderFactory.createLineBorder(Color.BLACK);
        setBounds(100,150,1400,500);
        setBorder(ColorfulLine);
        setLayout(null);
/*
        JLabel test = new JLabel();
        test.setBounds(175,50,50,100);
        test.setBorder(ColorfulLine);
        test.setVisible(true);
        add(test);

 */
    }
    public boolean Judge(Dominoes tmp){
        DirectionChange();
        if(isEmpty)return true;
        int p1,p2;
        p1 = tmp.point[0];
        p2 = tmp.point[1];
        if(tmp.isDouble){
            if(isFollowHead){
                return p1 == head;
            }else if(isFollowTail){
                return p1 == tail;
            }
        }
        if(isFollowHead){
            if(p1 == head){
                head = p2;
                if(HeadDirection.equals("left"))needHFlip = true;
                if(HeadDirection.equals("up"))needVFlip = true;
                return true;
            }else if(p2 == head){
                head = p1;
                if(HeadDirection.equals("right"))needHFlip = true;
                if(HeadDirection.equals("down"))needVFlip = true;
                return true;
            }else{
                return false;
            }
        }
        if(isFollowTail){
            if(p1 == tail){
                tail = p2;
                if(HeadDirection.equals("left"))needHFlip = true;
                if(HeadDirection.equals("up"))needVFlip = true;
                return true;
            }else if(p2 == tail){
                tail = p1;
                if(TailDirection.equals("down"))needVFlip = true;
                if(TailDirection.equals("right"))needHFlip = true;
                return true;
            }else{
                return false;
            }
        }
        return false;
    }
    public void PutDominoes(String name){
        int index = 0;
        String suffix = ".png";
        String imgPath;
        for(String s:DominoManager.Instance.DominoName){
            if(name.equals(s)){
                break;
            }
            index++;
        }
        Dominoes tmp = DominoManager.Instance.Library.get(index);
        if(isEmpty){
            imgPath = "./imageSrc/horizontal/"+tmp.name+suffix;
            ImageIcon icon = new ImageIcon(imgPath);
            JLabel label = new JLabel(icon);
            label.setBounds(PreHeadX,PreHeadY,100,50);
            PreHeadX += 100;
            label.setVisible(true);
            head = tmp.point[1];
            tail = tmp.point[0];
            add(label);//放牌
            repaint();//刷新显示
            MyLibrary.Instance.Update();//刷新手牌区显示(打出的牌删除)
            isEmpty = false;
            HeadDirection = "right";
            TailDirection = "down";
        }else{
            //System.out.println(HeadDirection+" "+TailDirection);
            System.out.println(isFollowHead+" "+isFollowTail);
            if(isFollowTail){
                DirectionPut(tmp,TailDirection);
            }else if(isFollowHead){
                DirectionPut(tmp,HeadDirection);
            }

                MyLibrary.Instance.Update();//刷新手牌区显示(打出的牌删除)

        }
        setFalse();
        System.out.println("put "+tmp.name);
        System.out.println("head:"+head+"tail:"+tail);
    }
    private void DirectionChange(){//转弯摆放判断
        int x,y;//100*50
        if(isFollowHead){
            switch (HeadDirection) {
                case "right" -> {
                    x = PreHeadX;
                    if (x + 100 >= 1300) {
                        HeadDirection = "down";
                        isRtoD = true;
                    }
                }
                case "down" -> {
                    y = PreHeadY;
                    if (y + 50 >= 425) {
                        HeadDirection = "left";
                        isDtoL = true;
                    }
                }
                case "left" -> {
                    x = PreHeadX;
                    if (x - 100 <= 75) {
                        HeadDirection = "up";
                        isLtoU = true;
                    }
                }
            }
        }else if(isFollowTail){
            switch (TailDirection) {
                case "down" -> {
                    y = PreTailY;
                    if (y + 50 >= 325) {
                        TailDirection = "right";
                        isDtoR = true;
                    }
                }
                case "right" -> {
                    x = PreTailX;
                    if (x + 100 >= 1300) {
                        TailDirection = "up";
                        isRtoU = true;
                    }
                }
                case "up" -> {
                    y = PreTailY;
                    if (y - 50 <= 75) {
                        TailDirection = "left";
                        isUtoL = true;
                    }
                }
            }
        }
    }
    private void DirectionPut(Dominoes dominoes,String Direction){
        System.out.println(dominoes.name+" "+Direction);
        int PreX = 0,PreY = 0;
        String imagePath;
        String suffix = ".png";
        if(dominoes.isDouble){//双排摆法
            if(Direction.equals("left")||Direction.equals("right")){
                imagePath = "./imageSrc/Vertical/"+dominoes.name + suffix;
            }else{
                if(PreTailX == PreTailY && PreTailY == 75){//第一张牌尾接双牌
                    imagePath = "./imageSrc/Vertical/"+dominoes.name + suffix;
                }else {
                    imagePath = "./imageSrc/horizontal/"+dominoes.name + suffix;
                }
            }
        if(isFollowHead){
            PreX = PreHeadX;
            PreY = PreHeadY;
            head = dominoes.point[1];
        }else{
            PreX = PreTailX;
            PreY = PreTailY;
            tail = dominoes.point[1];
        }
            ImageIcon icon = new ImageIcon(imagePath);
            JLabel jLabel = new JLabel(icon);
            switch (Direction){
               case "right"->{//双牌需竖摆
                   if(isDtoR){
                        imagePath = "./imageSrc/horizontal/"+dominoes.name + suffix;
                        ImageIcon  sp_icon = new ImageIcon(imagePath);
                        jLabel.setIcon(sp_icon);
                        jLabel.setBounds(PreX - 25,PreY + 100,100,50);
                        PreX += 75;
                        PreY += 100;
                        jLabel.setVisible(true);
                   }else {
                       jLabel.setBounds(PreX,PreY-25,50,100);
                       jLabel.setVisible(true);
                       PreX += 50;
                   }

               }
               case "down"->{
                   if (PreX == 75 && PreY == 75){
                       PreX -= 50;
                       PreY -= 25;
                       jLabel.setBounds(PreX,PreY,50,100);
                   }else{
                       jLabel.setBounds(PreX-25,PreY+100,100,50);
                       jLabel.setVisible(true);
                       PreY += 50;
                   }

               }
               case "left"->{
                   PreX -= 50;
                   jLabel.setBounds(PreX,PreY+25,50,100);
               }
               case "up"->{
                   if(isRtoU){
                       imagePath = "./imageSrc/Vertical/"+dominoes.name + suffix;
                       ImageIcon  sp_icon = new ImageIcon(imagePath);
                       jLabel.setIcon(sp_icon);
                       PreY -= 25;
                       jLabel.setBounds(PreX,PreY,50,100);
                   }else{
                       PreY += 50;
                       jLabel.setBounds(PreX - 25,PreY,100,50);
                   }
               }
           }
            add(jLabel);
            repaint();
        }else{
            if(Direction.equals("left")||Direction.equals("right")){
                imagePath = "./imageSrc/horizontal/"+dominoes.name + suffix;
            }else{
                imagePath = "./imageSrc/Vertical/"+dominoes.name + suffix;
            }
            if(isFollowHead){
                PreX = PreHeadX;
                PreY = PreHeadY;
            }else if(isFollowTail){
                PreX = PreTailX;
                PreY = PreTailY;
            }
            try{
                BufferedImage sourceImage = ImageIO.read(new FileInputStream(imagePath));
                BufferedImage image = sourceImage;
                if(needHFlip){
                    image = hTransform(sourceImage);
                    System.out.println("HT");
                }
                if(needVFlip){
                    System.out.println("VT");
                    image = vTransform(sourceImage);
                }
                JLabel jLabel = new JLabel(new ImageIcon(image));
                jLabel.setVisible(true);
                switch (Direction){
                    case "right"->{
                        if(isDtoR){//队尾左下角转弯
                            PreX += 50;
                            PreY += 50;
                        }
                        jLabel.setBounds(PreX,PreY,100,50);
                        PreX += 100;

                    }
                    case "down"->{
                        if(isRtoD){//队头右上转弯
                            PreY += 50;
                            PreX -= 50;
                            jLabel.setBounds(PreX,PreY,50,100);
                        }else{ //往下
                            if (PreTailX == 75 && PreTailY == 75) {//从尾开始的第一张牌
                                //第一张牌横放高50，往下则Y坐标+50
                                PreY += 50;
                            } else {//正常往下
                                PreY += 100;
                            }
                            jLabel.setBounds(PreX, PreY, 50, 100);
                        }
                    }
                    case "left"->{/*
                            由于参照点位于左上角，UtoL与正常L重合故无需考虑
                            * */
                        if(isDtoL){
                            PreX -= 50;
                            PreY += 100;
                            jLabel.setBounds(PreX,PreY,100,50);
                        }else{
                            PreX -= 100;
                            jLabel.setBounds(PreX,PreY,100,50);
                        }
                    }
                    case "up"->{
                        /* 参照点位于左上角，使得LtoU与正常U一样
                        if(isLtoU){
                            PreY += 100;
                            jLabel.setBounds(PreX,PreY,50,100);
                        }
                        */
                        if(isRtoU){
                            PreX -= 50;
                        }else{
                            PreY += 100;
                        }
                        jLabel.setBounds(PreX,PreY,50,100);
                    }
                }
                add(jLabel);
                repaint();
            }catch (Exception e){
                e.printStackTrace();
            }

        }
        if(isFollowHead){
            PreHeadX = PreX;
            PreHeadY = PreY;
        }
        if(isFollowTail){
            PreTailX = PreX;
            PreTailY = PreY;
        }
        System.out.println("X:"+PreX+" "+"Y:"+PreY);
    }

    private BufferedImage hTransform(BufferedImage sourceImage){
        AffineTransform transform = new AffineTransform(-1,0,0,1,sourceImage.getWidth()-1,0);
        AffineTransformOp  op = new AffineTransformOp(transform,AffineTransformOp.TYPE_BILINEAR);
        return op.filter(sourceImage,null);
    }

    private BufferedImage vTransform(BufferedImage sourceImage){
        AffineTransform transform = new AffineTransform(1,0,0,-1,0,sourceImage.getHeight()-1);
        AffineTransformOp  op = new AffineTransformOp(transform,AffineTransformOp.TYPE_BILINEAR);
        return op.filter(sourceImage,null);
    }


    private void setFalse(){
        isFollowHead = false;
        isFollowTail = false;
        needHFlip = false;
        needVFlip = false;
        isRtoD = isDtoL = isLtoU = isDtoR = isRtoU = isUtoL = false;
    }
}
